import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

/**
 * This holds an array list of functional dependencies.
 * 
 * @relation - the ArrayList of FunctionalDependency objects
 * @relationName - this is only used when put into a RelationHolder object.
 * @key - the key of the relation. Only updated after the creation of the
 *      relation.
 *      
 * @author Sean Clapp
 * 
 */
public class Relation {
	private ArrayList<FunctionalDependency> relation;
	private String relationName;
	@SuppressWarnings("rawtypes")
	private Set key, setOfAllAttribs;

	/**
	 * Constructor class for the Relation object
	 */
	public Relation() {
		super();
		this.relation = new ArrayList<FunctionalDependency>();
	}

	/**
	 * **GETTER ONLY**
	 * 
	 * @return the set of all attributes of a relation (U)
	 */
	@SuppressWarnings("rawtypes")
	public Set getSetOfAllAttribs() {
		return setOfAllAttribs;
	}

	/**
	 * Stores the set of all attributes in a relation to a set for use by other
	 * classes
	 * 
	 * @param setOfAllAttribs
	 *            - The set of all attribtues, given a Relation
	 */
	@SuppressWarnings("rawtypes")
	public void setSetOfAllAttribs(Set setOfAllAttribs) {
		this.setOfAllAttribs = setOfAllAttribs;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void generateSetOfAllAttribs() {
		Set setOfAttribs = new HashSet();
		for (int i = 0; i < this.relation.size(); i++) {
			FunctionalDependency fd = this.relation.get(i);
			setOfAttribs.addAll(fd.getKey());
			setOfAttribs.addAll(fd.getValue());
		}
		this.setOfAllAttribs = setOfAttribs;
	}

	/**
	 * **GETTER only** Returns the key of this relation. The key is the minimal
	 * set of attributes that determines every attribute in the relation
	 * 
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Set getKey() {
		return key;
	}

	/**
	 * 
	 * **SETTER ONLY** Sets the key of this relation to the given set
	 * 
	 * @param key
	 */
	@SuppressWarnings("rawtypes")
	public void setKey(Set key) {
		this.key = key;
	}

	/**
	 * Returns the ArrayList<FunctionalDependency> relation
	 * 
	 * @return
	 */
	public ArrayList<FunctionalDependency> getRelation() {
		return relation;
	}

	public void setRelation(ArrayList<FunctionalDependency> relation) {
		this.relation = relation;
	}

	/**
	 * Gets the relation name **NOTE** this is not the key of the hashmap, it is
	 * a more descriptive name usually displayed to the user when the user needs
	 * to see the name of the relation they are dealing with.
	 * 
	 * @return relationName
	 */
	public String getRelationName() {
		return relationName;
	}

	/**
	 * sets the relation name **NOTE** this is NOT the key of the hashmap,
	 * instead it is a more descriptive name used to give more info to the user.
	 * 
	 * @param relationName
	 */
	public void setRelationName(String relationName) {
		this.relationName = relationName;
	}

	/**
	 * prints contents of this relation
	 */
	public void print() {
		
		for (int i = 0; i < this.relation.size(); i++) {

			FunctionalDependency fd = this.relation.get(i);
			if (!fd.getKey().isEmpty()) {
				String left = fd.getKey().toString();
				String right = fd.getValue().toString();
				if (fd.isMultiVal()) {
					System.out.print(left + ";" + right);
				} else if (left.length() > 0) {
					System.out.print(left + ">" + right);
				}
			}
			if(i<this.relation.size()-1){
				System.out.print(" , ");
			}
		}
	}
}
